package modelo.enemigos;

// paquetes del proyecto
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import modelo.interfaces.Manejador;
import modelo.juego.Configuracion;
import modelo.juego.Jugador;
import modelo.mapa.Mapa;

public class ManejadorEnemigos implements Manejador, Serializable {

	private static final long serialVersionUID = -1818317248615176397L;
	private Jugador jugador;
	private Mapa mapa;
	private Collection<Enemigo> listaEnemigos;
	private long temporizador;
	private int intervaloDeCreacionDeEnemigos;
	private CreadorEnemigo tipoDeEnemigoDelNivel;

	public ManejadorEnemigos(Mapa mapaManager, Jugador player, int intervalo,
			CreadorEnemigo TipoDeEnemigo) {
		mapa = mapaManager;
		jugador = player;
		temporizador = 0;
		intervaloDeCreacionDeEnemigos = intervalo;
		tipoDeEnemigoDelNivel = TipoDeEnemigo;
		listaEnemigos = new LinkedList<Enemigo>();
	}

	public void Resetear_Velocidad(Enemigo enemigo) {// Redundante???
	}

	public Collection<Enemigo> getListaEnemigos() {
		return listaEnemigos;
	}

	public void modificarVelocidad(Enemigo enemigo, double factor) {
		enemigo.CambiarVelocidad(factor);
	}

	public void congelar(Enemigo enemigo, boolean estado) {
		enemigo.Congelar(estado);
	}

	public void Daniar(Enemigo enemigo, int danio) {
		enemigo.Daniar(danio);
		if (enemigo.getResistencia() <= 0) {
			removerEnemigo(enemigo);
			jugador.modificarDinero(enemigo.dineroPorEliminacion());
		}
	}

	public void latir() {

		++temporizador;
		Iterator<Enemigo> enemigos = listaEnemigos.iterator();

		// Recorro mi lista de enemigos y hago avanzar a todos los enemigos q
		// tengo. Si alguno esta en el ultimo casillero, lo elimino y le resto
		// vida al jugador.
		while (enemigos.hasNext()) {
			Enemigo enemigoActual = enemigos.next();

			try {
				enemigoActual.avanzar(mapa);
								
			} catch (ExceptionPasoUltimoCasillero cruzo) {
				jugador.modificarVida(Configuracion.VIDA_X_ESCAPAR_ENEMIGO);
				enemigoActual.setLlego(true);
				//removerEnemigo(enemigoActual);
			}
		}
		
		removerEnemigos();
		
		if ((temporizador > Configuracion.PERIODO_DE_GRACIA)
				&& (temporizador % intervaloDeCreacionDeEnemigos == 0)){
			crearEnemigo();
		}
		if (temporizador == Configuracion.CAMBIO_DE_NIVEL1) {
			cambiarTipoEnemigo(new CreadorArania());
			intervaloDeCreacionDeEnemigos = 20;
		}
		
		if (temporizador == Configuracion.CAMBIO_DE_NIVEL2) {
			cambiarTipoEnemigo(new CreadorCucaracha());
			intervaloDeCreacionDeEnemigos = 25;
		}
		
		if (temporizador == Configuracion.CAMBIO_DE_NIVEL3) {
			cambiarTipoEnemigo(new CreadorMosca());
			intervaloDeCreacionDeEnemigos = 20;
		}
		
		if ((temporizador > Configuracion.CAMBIO_DE_NIVEL4) && (temporizador % 100 == 0)){
			Random generator = new Random( 4 );
			int numero = generator.nextInt();
			switch (numero) {
				case 1:	cambiarTipoEnemigo(new CreadorHormiga());
					break;
				case 2: cambiarTipoEnemigo(new CreadorCucaracha());
					break;
				case 3: cambiarTipoEnemigo(new CreadorArania());
					break;
				case 4: cambiarTipoEnemigo(new CreadorMosca());
					break;
			}
			if (intervaloDeCreacionDeEnemigos > 2)
			intervaloDeCreacionDeEnemigos -= 2; 			
		}
	}

	private void removerEnemigos() {
		Collection<Enemigo> nuevaLista = new LinkedList<Enemigo>();
		Iterator<Enemigo> enemigos = listaEnemigos.iterator();
		while (enemigos.hasNext()) {
			Enemigo enemigoActual = enemigos.next();
			if (!(enemigoActual.llego())) {
				nuevaLista.add(enemigoActual);
			} else {
				mapa.removerPosicionable(enemigoActual);
			}
		}
		
		listaEnemigos = nuevaLista;
	}
	
	protected void crearEnemigo() {
		Enemigo unEnemigo = tipoDeEnemigoDelNivel.crearEnemigo(mapa.primeraPosicion());
		listaEnemigos.add(unEnemigo);
		mapa.posicionarPosicionable(mapa.primeraPosicion(), unEnemigo);
	}

	protected void removerEnemigo(Enemigo unEnemigo) throws RuntimeException {
		mapa.removerPosicionable(unEnemigo);
		if ((listaEnemigos.remove(unEnemigo)) == false) { 
			throw new RuntimeException("El enemigo eliminado no estaba en la lista de enemigos");
		}
		
	}

	public void cambiarTipoEnemigo(CreadorEnemigo nuevoTipoEnemigo) {
		tipoDeEnemigoDelNivel = nuevoTipoEnemigo;
	}

	public void redibujarComponentes(){
		Iterator<Enemigo> enemigos = listaEnemigos.iterator();
		while (enemigos.hasNext()) {
			Enemigo enemigoActual = enemigos.next();
			enemigoActual.RecrearVista();
		}

	}
}